home *** CD-ROM | disk | FTP | other *** search
/ NeXT Enterprise Objects Framework 1.1 / NeXT Enterprise Objects Framework 1.1.iso / NextDeveloper / Headers / foundation / NSException.h < prev    next >
Text File  |  1994-09-13  |  9KB  |  235 lines

  1. /*    NSException.h
  2.       Copyright 1994, NeXT, Inc.
  3.     NeXT, April 1994
  4. */
  5.  
  6. #import <foundation/NSDictionary.h>
  7. #include <setjmp.h>
  8.  
  9. #if defined(NeXT_PDO) && defined(__svr4__)
  10. #define _setjmp setjmp
  11. #define _longjmp longjmp
  12. #endif
  13.  
  14. /***************    Exception names        ***************/
  15.  
  16. extern NSString *NSGenericException;
  17. extern NSString *NSRangeException;
  18. extern NSString *NSInvalidArgumentException;
  19. extern NSString *NSParseErrorException;
  20. extern NSString *NSInternalInconsistencyException;
  21. extern NSString *NSObjCInadequateRuntimeInformation;
  22.  
  23. extern NSString *NSCodingException;
  24. extern NSString *NSObjectInaccessibleException;
  25. extern NSString *NSObjectNotAvailableException;
  26. extern NSString *NSDestinationInvalidException;
  27. extern NSString *NSOwnershipTransferException;
  28.     
  29. extern NSString *NSPortTimoutException;
  30. extern NSString *NSInvalidSendPort;
  31. extern NSString *NSInvalidReceivePort;
  32. extern NSString *NSPortSendError;
  33. extern NSString *NSPortReceiveError;
  34. extern NSString *NSPortNameRegistrationError;
  35.  
  36. extern NSString *NSArchiverArchiveInconsistency;
  37. extern NSString *NSArchiverClassError;
  38. extern NSString *NSArchiverDescriptorError;
  39. extern NSString *NSArchiverWriteReferenceError;
  40.  
  41. extern NSString *NSDateMissingTimeZone;
  42.  
  43. /***************    Exception object    ***************/
  44.  
  45. @interface NSException:NSObject <NSCopying> {
  46.     /* Exceptions are immutable, although they may retain objects in a dictionary that may be mutable;
  47.     Note that -description is used when an exception is reported and can be redefined */
  48.     NSString        *name;        /* Exception name */
  49.     NSString        *reason;     /* Human readable reason for raising */
  50.     NSDictionary    *userInfo;    /* Any arbitrary other data */
  51. }
  52.  
  53. + (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
  54.     /* Creates an autoreleased exception */
  55.  
  56. - (NSString *)exceptionName;
  57.  
  58. - (NSString *)exceptionReason;
  59.  
  60. - (NSDictionary *)exceptionUserInfo;
  61.     /* May return nil */
  62.  
  63. - (volatile void)raise;
  64.     /* Dispatches according to the appropriate catcher;
  65.     Never returns */
  66.  
  67. - initWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
  68.     /* Designated initializer */
  69.  
  70. @end
  71.  
  72. /***************    Conveniences for raising    ***************/
  73.  
  74. @interface NSException (NSExceptionRaisingConveniences)
  75.  
  76. + (volatile void)raise:(NSString *)name format:(NSString *)format, ...;
  77.     /* Create an exception then raise it; 
  78.     format is used to create the exception 'reason' */
  79.  
  80. + (volatile void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
  81.  
  82. @end
  83.  
  84. /***************    Raising and catching    ***************/
  85.  
  86. #define NSExceptionBase 100000 // TEMPORARY!
  87. #define NSLastException 100999 // TEMPORARY!
  88.  
  89. // Private definition
  90. typedef struct _NSHandler {    /* a node in the handler chain */
  91.     jmp_buf        jumpState;    /* place to longjmp to */
  92.     struct _NSHandler    *next;        /* ptr to next handler */
  93.     int         code;        /* error code of exception; always >=NSExceptionBase and <=NSLastException for now */
  94.     const void        *data1;        /* The exception object */
  95.     const void        *data2;        /* Reserved for compatibility */
  96. } NSHandler;
  97.  
  98. /* NS_DURING, NS_HANDLER and NS_ENDHANDLER are always used like:
  99.  
  100.     NS_DURING
  101.         some code which might raise an error
  102.     NS_HANDLER
  103.         code that will be jumped to if an error occurs
  104.     NS_ENDHANDLER
  105.  
  106.    If any error is raised within the first block of code, the second block of code will be jumped to.  Typically, this code will clean up any resources allocated in the routine, possibly case on the error code and perform special processing, and default to -raise again the exception to the next handler.  Within the scope of the handler, a local variable called 'exception' holds the raised exception.
  107.    It is illegal to exit the first block of code by any other means than
  108.    NS_VALRETURN, NS_VOIDRETURN, or just falling out the bottom.
  109.  */
  110.  
  111. /* private support routines.  Do not call directly. */
  112. extern void _NSAddHandler(NSHandler *handler);
  113. extern void _NSRemoveHandler(NSHandler *handler);
  114. extern _setjmp(jmp_buf env);
  115.  
  116. #define NS_DURING { NSHandler _localHandler;            \
  117.             _NSAddHandler(&_localHandler);        \
  118.             if( !_setjmp(_localHandler.jumpState) ) {
  119.  
  120. #define NS_HANDLER _NSRemoveHandler(&_localHandler); } else { \
  121.             NSException    *exception = (_localHandler.code >= NSExceptionBase && _localHandler.code <= NSLastException) ? (id)_localHandler.data1 : nil;
  122.  
  123. #define NS_ENDHANDLER exception = nil; /* to avoid compiler warning */}}
  124.  
  125. #define NS_VALRETURN(val)  do { typeof(val) temp = (val);    \
  126.             _NSRemoveHandler(&_localHandler);    \
  127.             return(temp); } while (0)
  128.  
  129. #define NS_VOIDRETURN    do { _NSRemoveHandler(&_localHandler);    \
  130.             return; } while (0)
  131.  
  132. /***************    Changing the top level error catcher    ***********/
  133.  
  134. /* The top level error catcher can be set to look for certain exceptions, do some work, and then either abort or call the previous top level error catcher */
  135.  
  136. typedef volatile void NSUncaughtExceptionHandler(NSException *exception);
  137.  
  138. extern NSUncaughtExceptionHandler *NSGetUncaughtExceptionHandler(void);
  139. extern void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler *);
  140.  
  141. /***********    Assertion of program consistency        ***********/
  142.  
  143. /* Assertions evaluate a condition, and if it is false, they call the NSAssertionHandler for the current thread to report that fact.  The assertion macros also take a "description" argument, which should describe the failure that is being tested for.  The description is a printf-style format NSString.  N args may be passed using the NSAssertN() variations.  When calling from within a method, the object's class and method name need not be included in the description, since those args are passed separately.
  144.  
  145. Assertions are compiled into code if the cpp macro NS_BLOCK_ASSERTIONS is defined.  Runtime control is achieved by substituting a different assertion handler.
  146.  
  147. Since these macros pass the variables "self" and "_cmd" automatically, they assume that they are being called from within a method context. There is a parallel set of macros for use within C functions. 
  148. */
  149.  
  150.  
  151. @class NSAssertionHandler;
  152.  
  153. /* Implementation of asserts (ignore) */
  154. #ifdef NS_BLOCK_ASSERTIONS
  155. #define _NSAssertBody(condition, desc, arg1, arg2, arg3)    \
  156.     do {                        \
  157.     if (!(condition)) {                \
  158.         [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithCString:__FILE__] lineNumber:__LINE__ description:(desc), (arg1), (arg2), (arg3)];    \
  159.     }                        \
  160.     } while(0)
  161. #define _NSCAssertBody(condition, desc, arg1, arg2, arg3)    \
  162.     do {                        \
  163.     if (!(condition)) {                \
  164.         [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__] file:[NSString stringWithCString:__FILE__] lineNumber:__LINE__ description:(desc), (arg1), (arg2), (arg3)];    \
  165.     }                        \
  166.     } while(0)
  167. #else
  168. #define _NSAssertBody(condition, desc, arg1, arg2, arg3)
  169. #define _NSCAssertBody(condition, desc, arg1, arg2, arg3)
  170. #endif
  171.  
  172.  
  173. /*
  174.  * Asserts to use in Objective-C method bodies
  175.  */
  176.  
  177. #define NSAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5)    \
  178.     _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), (arg5))
  179.  
  180. #define NSAssert4(condition, desc, arg1, arg2, arg3, arg4)    \
  181.     _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4))
  182.  
  183. #define NSAssert3(condition, desc, arg1, arg2, arg3)    \
  184.     _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3))
  185.  
  186. #define NSAssert2(condition, desc, arg1, arg2)        \
  187.     _NSAssertBody((condition), (desc), (arg1), (arg2), 0)
  188.  
  189. #define NSAssert1(condition, desc, arg1)        \
  190.     _NSAssertBody((condition), (desc), (arg1), 0, 0)
  191.  
  192. #define NSAssert(condition, desc)            \
  193.     _NSAssertBody((condition), (desc), 0, 0, 0)
  194.  
  195. /* convenience for validating parameters.  The text of the condition that fails is passed to the handler. */
  196. #define NSParameterAssert(condition)            \
  197.     _NSAssertBody((condition), @"Invalid parameter not satisfying: %s", #condition, 0, 0)
  198.  
  199. /*
  200.  * Asserts to use in C function bodies
  201.  */
  202.  
  203. #define NSCAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5)    \
  204.     _NSCAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), (arg5))
  205.  
  206. #define NSCAssert4(condition, desc, arg1, arg2, arg3, arg4)    \
  207.     _NSCAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4))
  208.  
  209. #define NSCAssert3(condition, desc, arg1, arg2, arg3)    \
  210.     _NSCAssertBody((condition), (desc), (arg1), (arg2), arg3)
  211.  
  212. #define NSCAssert2(condition, desc, arg1, arg2)    \
  213.     _NSCAssertBody((condition), (desc), (arg1), (arg2), 0)
  214.  
  215. #define NSCAssert1(condition, desc, arg1)        \
  216.     _NSCAssertBody((condition), (desc), (arg1), 0, 0)
  217.  
  218. #define NSCAssert(condition, desc)            \
  219.     _NSCAssertBody((condition), (desc), 0, 0, 0)
  220.  
  221. /* convenience for validating parameters.  The text of the condition that fails is passed to the handler. */
  222. #define NSCParameterAssert(condition)            \
  223.     _NSCAssertBody((condition), @"Invalid parameter not satisfying: %s", #condition, 0, 0)
  224.  
  225.  
  226. @interface NSAssertionHandler : NSObject
  227.  
  228. + (NSAssertionHandler *)currentHandler;
  229.  
  230. - (void)handleFailureInMethod:(SEL)selector object:object file:(NSString *)fileName lineNumber:(int)line description:(NSString *)format,...;
  231.  
  232. - (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(int)line description:(NSString *)format,...;
  233.  
  234. @end
  235.